package com.minivision.fdiot.rest;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;

import com.minivision.fdiot.entity.Face;
import com.minivision.fdiot.service.FaceCommonService;
import com.minivision.fdiot.util.FeatureUtils;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import net.sf.ehcache.Cache;
import net.sf.ehcache.Element;

@Controller
@RequestMapping(value = "/features", method = RequestMethod.GET)
@Api(tags = "FeatureSetApi", value = "FeatureSet Apis")
@Slf4j
public class FeatureSetApi {
  
  @Autowired
  private FaceCommonService commonService;
  
  @Autowired
  private RedisTemplate<String, float[]> featureTemplate;
  
//  @Autowired
//  private Cache downloadTokenCache;

  @Autowired
  private StringRedisTemplate stringRedisTemplate;
  
  //public static Map<String, String> downloadContext = new ConcurrentHashMap<>();
  
  @GetMapping("/download/{setToken}")
  @ApiOperation(value="下载人脸库", notes="下载人脸库，不需要鉴权，程序中不需要Token头，Swagger上可填个随意字符串即可")
  @ApiImplicitParams(value = {
      @ApiImplicitParam(name = "downloadToken", value = "下载令牌", paramType = "query", dataType = "String", required = true)
  })
  public ResponseEntity<StreamingResponseBody> download(@PathVariable("setToken") String setToken, @RequestParam("downloadToken") String downloadToken) {
    String faceSetToken = stringRedisTemplate.opsForValue().get(downloadToken);
    if(StringUtils.isNoneEmpty(downloadToken) && faceSetToken != null && setToken.equals(faceSetToken)){
      stringRedisTemplate.delete(downloadToken);
      //downloadTokenCache.remove(downloadToken);
      HttpHeaders headers = new HttpHeaders(); 
      Map<String, float[]> features = commonService.getAllFeaturesOfFaceSet(setToken);
      headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
      headers.setContentDispositionFormData("attachment", "faceset-"+setToken); 
      int count = features.size();
      int featureSize = features.values().stream().findAny().orElse(new float[0]).length;
      headers.setContentLength(4 + 4 + count * (16 + featureSize * 4));
      return new ResponseEntity<StreamingResponseBody>(new StreamingResponseBody() {
        @Override
        public void writeTo(OutputStream os) throws IOException {
          FeatureUtils.encodeFaceSet(features, os);
        }
      }, headers, HttpStatus.CREATED);
    }else{
      return new ResponseEntity<>(HttpStatus.NOT_FOUND);
    }
  }
  
  @GetMapping("/{faceToken}")
  @ResponseBody
  @ApiOperation(hidden = true, value = "获取人脸特征值")
  public String getFeatures(@PathVariable("faceToken") String faceToken) {
    Face faceInfo = commonService.findFaceInfo(faceToken);
    log.info(faceToken + "->" + faceInfo);
    float[] features = featureTemplate.opsForValue().get("faces:" + faceToken + ":feature");
    if (features == null) {
      return "face[" + faceToken + "] not exists";
    }
    String result = "";
    for (float f : features) {
      result += f + "<br/>";
    }
    return result;
  }
  
}
